package com.ueffort.ad;

import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import com.ueffort.ad.action.PreloadAction;
import com.ueffort.ad.action.ShowAction;
import com.unity3d.player.UnityPlayer;

import java.lang.reflect.InvocationTargetException;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;

public class AdSDK {
    static Activity mActivity;
    static UnityPlayer unityPlayer;
    public enum AdPlatformType{
        GoogleMobile,
        Unity,
        YomobGoogle,
        YomobChina,
        Mi,
        Huawei,
        Uc,
    }
    public enum AdType
    {
        Banner,
        Interstitial,
        Reward,
    }
    private static AdPlatformType[] platformList = {
            AdPlatformType.GoogleMobile,
            AdPlatformType.Unity,
            AdPlatformType.YomobGoogle,
            AdPlatformType.YomobChina,
            AdPlatformType.Mi,
            AdPlatformType.Huawei,
            AdPlatformType.Uc,
    };
    private static AdType[] typeList = {
            AdType.Banner,
            AdType.Interstitial,
            AdType.Reward,
    };
    private static Dictionary<AdPlatformType, String> platformClassDefine = new Hashtable<AdPlatformType, String>(){
        {
            platformClassDefine.put(AdPlatformType.Mi, "com.ueffort.ad.platform.MiProvider");
            platformClassDefine.put(AdPlatformType.Huawei, "com.ueffort.ad.platform.HuaweiProvider");
            platformClassDefine.put(AdPlatformType.Uc, "com.ueffort.ad.platform.UcProvider");
        }
    };
    private static Dictionary<AdPlatformType, AdProvider> mPlatformList=new Hashtable<>();
    private static AdCallbackListener callbackListener;
    static {
        mActivity = UnityPlayer.currentActivity;
        View rootView = mActivity.findViewById(android.R.id.content);
        unityPlayer = findUnityPlayerView(rootView);
        try {
            Enumeration<AdPlatformType> a = platformClassDefine.keys();
            while(a.hasMoreElements()){
                AdPlatformType p = a.nextElement();
                Class cls = Class.forName(platformClassDefine.get(p));
                if(null != cls){
                    mPlatformList.put(p, (AdProvider) cls.getMethod("Instance").invoke(null));
                }
            }
            checkActivity();
        } catch (ClassNotFoundException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public static void onActivityResult(int requestCode, int resultCode, Intent data){
        Enumeration<AdProvider> e = mPlatformList.elements();
        while(e.hasMoreElements()){
            AdProvider provider = e.nextElement();
            if (provider.onActivityResult(requestCode, resultCode, data)) {
                break;
            }
        }
    }

    private static int getPlatform(AdPlatformType platformType){
        for (int i = 0; i < platformList.length; i++) {
            if (platformType == platformList[i]) {
                return i;
            }
        }
        return -1;
    }
    private static AdPlatformType getPlatform(int location) {
        int length = platformList.length;
        return location >= 0 && location < length?platformList[location]:null;
    }
    private static AdType getType(int location){
        int length = typeList.length;
        return location >= 0 && location < length ? typeList[location]:null;
    }
    public static void register(int platform, String appId, final AdRegisterListener listener){
        checkActivity();
        Log.e("ad", "register: "+getPlatform(platform));
        if (getPlatform(platform)==null){
            runInUI(new Runnable() {
                @Override
                public void run() {
                    listener.onRegister(platform, false);
                }
            });
            return;
        }

        AdProvider provider = mPlatformList.get(getPlatform(platform));
        Log.e("ad", "register: "+provider);
        if (provider==null){
            runInUI(new Runnable() {
                @Override
                public void run() {
                    listener.onRegister(platform, false);
                }
            });
            return;
        }
        try{
            provider.Init(appId, mActivity, unityPlayer);
            runInUI(new Runnable() {
                @Override
                public void run() {
                    listener.onRegister(platform, true);
                }
            });
        }catch (Exception e){

            Log.e("ad", e.getLocalizedMessage());
        }
    }
    public static void bindCallback(AdCallbackListener listener){
        callbackListener = listener;
    }

    public static void setDebugMode(int platform, boolean isTest){
        AdProvider provider = mPlatformList.get(getPlatform(platform));
        Log.e("ad", "setDebugMode: "+provider+":");
        provider.SetDebugMode(isTest);
    }

    public static void preload(int platform, int type, String unitId){
        AdType adType = getType(type);
        AdProvider provider = mPlatformList.get(getPlatform(platform));
        Log.e("ad", "Preload: "+provider+":"+unitId);
        provider.Preload(adType, unitId, new PreloadAction() {
            @Override
            public void OnSuccess() {
                callbackListener.OnPreloadAdSuccess("");
            }
            @Override
            public void OnFail (String errorMsg) {
                callbackListener.OnPreloadAdFailed(errorMsg);
            }
        });
    }

    public static boolean isLoaded(int platform, int type, String unitId){
        AdType adType = getType(type);
        AdProvider provider = mPlatformList.get(getPlatform(platform));
        Log.e("ad", "IsLoaded: "+provider+":"+unitId);
        return provider.IsLoaded(adType, unitId);
    }

    public static void show(int platform, int type, String unitId){
        AdType adType = getType(type);
        AdProvider provider = mPlatformList.get(getPlatform(platform));
        Log.e("ad", "Show: "+provider+":"+unitId);
        provider.Show(adType, unitId, new ShowAction() {
            @Override
            public void OnShowSuccess() {
                callbackListener.OnAdShowSuccess("","");
            }
            @Override
            public void OnShowFail(String errorMsg) {
                callbackListener.OnAdShowFailed("", "", errorMsg);
            }
            @Override
            public void OnVideoShow() {
                callbackListener.OnAwardVideoLoadedCallback("");
            }
            @Override
            public void OnClick() {
                callbackListener.OnAdClick("", "");
            }
            @Override
            public void OnClose(boolean reward) {
                callbackListener.OnAdClose("", "", reward);
            }
        });
    }

    private static void runInUI(Runnable runnable) {
        mActivity.runOnUiThread(runnable);
    }
    private static String getFileName(String fullname) {
        return !fullname.startsWith("assets/") && !fullname.startsWith("res/")?"":fullname.split("/")[1];
    }

    public static void updateOwnerActivity(Activity activity) {
        mActivity = activity;
    }

    private static void checkActivity() {
        assert mActivity != null : "在AdSDK类中, mActivity为null.";
    }

    private static UnityPlayer findUnityPlayerView(View view) {

        if (view instanceof UnityPlayer) {

            return (UnityPlayer) view;
        }
        if (view instanceof ViewGroup) {

            ViewGroup childrenViews = (ViewGroup) view;

            for (int i = 0; i < childrenViews.getChildCount(); i++) {

                UnityPlayer foundView = findUnityPlayerView(childrenViews.getChildAt(i));

                if (foundView != null) {

                    return foundView;
                }
            }
        }

        return null;
    }
}
